import axios, { AxiosResponse } from 'axios'
// AxiosRequestConfig
import type { AxiosInstance, InternalAxiosRequestConfig } from 'axios'
import type { RequestConfig, RequestInterceptors } from './type'

class Request {
  // axios 实例
  instance: AxiosInstance
  // 拦截器对象
  interceptorsObj?: RequestInterceptors

  constructor(config: RequestConfig) {
    console.log('初始化')

    // axios.request();
    // 这个地方 axios内部修改了(v1.7.7)。config 默认是CreateAxiosDefaults AxiosRequestConfig
    this.instance = axios.create(config)
    this.interceptorsObj = config.interceptors

    // 存在多个拦截器的时候
    // 请求拦截器: 先进后出，会先执行最后指定的拦截器
    // 响应拦截器: 先进先出，会先执行先指定的拦截器，按照顺序执行
    // 全局 请求拦截器
    this.instance.interceptors.request.use(
      // (res: AxiosRequestConfig) => {
      (res: InternalAxiosRequestConfig) => {
        console.log('全局的请求拦截器~~')
        return res
      },
      (err: any) => err
    )

    // 实例 请求拦截器
    this.instance.interceptors.request.use(
      this.interceptorsObj?.requestInterceptors,
      this.interceptorsObj?.requestInterceptorsCatch
    )
    // 全局 响应拦截器
    this.instance.interceptors.response.use(
      // 因为我们接口的数据都在res.data下，所以我们直接返回res.data
      (res: AxiosResponse) => {
        console.log('全局响应拦截器:成功', '')

        return res.data
      },
      (err: any) => {
        // 判断状态码
        console.log('全局响应拦截器:失败', err)
        // return err
        // 失败的话，必须通过 Promise.reject 返回出去，不然会走到下一个拦截器的成功回调
        return Promise.reject(err)
      }
    )
    // 实例 响应拦截器
    this.instance.interceptors.response.use(
      this.interceptorsObj?.responseInterceptors,
      this.interceptorsObj?.responseInterceptorsCatch
    )
  }
  // 1、备注
  // request(config: RequestConfig) {
  //   // 每次调接口的时候，每个接口也有一个请求拦截器和响应拦截器， 其实就是一个函数
  //   if (config.interceptors?.requestInterceptors) {
  //     // 这里其实不是一个真正意义上的拦截器，就是掉了一个函数，然后 返回 config
  //     config = config.interceptors.requestInterceptors(config as any);
  //   }
  //   this.instance.request(config).then((res) => {
  //     if (config.interceptors?.responseInterceptors) {
  //       res = config.interceptors.responseInterceptors(res);
  //     }
  //     console.log("res", res);
  //   });
  // }
  request<T>(config: RequestConfig): Promise<T> {
    return new Promise((resolve, reject) => {
      // 每次调接口的时候，每个接口也有一个请求拦截器和响应拦截器， 其实就是一个函数
      if (config.interceptors?.requestInterceptors) {
        // 这里其实不是一个真正意义上的拦截器，就是掉了一个函数，然后 返回 config
        config = config.interceptors.requestInterceptors(config as any)
        // config = config.interceptors.requestInterceptors(config);
      }
      this.instance.request<any, T>(config).then(
        (res) => {
          if (config.interceptors?.responseInterceptors) {
            res = config.interceptors.responseInterceptors(res)
          }
          console.log('走到了封装里面的成功:', res)

          resolve(res)
        },
        (err) => {
          console.log('走到了封装里面的失败:', err)
          reject(err)
          return err
        }
      )
    })
  }

  // request(config: AxiosRequestConfig) {
  // return this.instance.request(config);
  // }
  // request<T>(config: RequestConfig): Promise<T> {
  //   return new Promise((resolve, reject) => {
  //     // 如果我们为单个请求设置拦截器，这里使用单个请求的拦截器
  //     if (config.interceptors?.requestInterceptors) {
  //       config = config.interceptors.requestInterceptors(config as any);
  //     }
  //     this.instance
  //       .request<any, T>(config)
  //       .then((res) => {
  //         // 如果我们为单个响应设置拦截器，这里使用单个响应的拦截器
  //         if (config.interceptors?.responseInterceptors) {
  //           // res = config.interceptors.responseInterceptors<T>(res);
  //           // res = config.interceptors.responseInterceptors(res);
  //           // res = config.interceptors.responseInterceptors(res);
  //         }

  //         resolve(res);
  //       })
  //       .catch((err: any) => {
  //         reject(err);
  //       });
  //   });
  // }
}

export default Request
